package com.ddw.meedeeuh.shared.movie;

import java.io.File;
import java.util.Properties;
import java.util.regex.Pattern;

import com.ddw.meedeeuh.shared.GlobalSettingsFactory;
import com.ddw.meedeeuh.shared.PropertiesUtils;
import com.ddw.meedeeuh.shared.movie.MovieSettings.MovieExportNodes;
import com.ddw.meedeeuh.shared.movie.MovieSettings.MovieNfoConstants;

public abstract class MovieSettingsFactory {

	private static final String EXPORT_PRETTY_FORMAT = "movie.export.prettyNfos";
	private static final String EXPORT_ADD_EMPTY_NODES = "movie.export.addEmptyNodes";
	private static final String EXPORT_ELEMENT_MOVIE = "movie.export.elements.movie";
	private static final String EXPORT_ELEMENT_MOVIE_TITLE = "movie.export.elements.movie.title";
	private static final String EXPORT_ELEMENT_MOVIE_ORIGINALTITLE = "movie.export.elements.movie.originalTitle";
	private static final String EXPORT_ELEMENT_MOVIE_SORTTITLE = "movie.export.elements.movie.sortTitle";
	private static final String EXPORT_ELEMENT_MOVIE_RATING = "movie.export.elements.movie.rating";
	private static final String EXPORT_ELEMENT_MOVIE_YEAR = "movie.export.elements.movie.year";
	private static final String EXPORT_ELEMENT_MOVIE_TOP250 = "movie.export.elements.movie.top250";
	private static final String EXPORT_ELEMENT_MOVIE_VOTES = "movie.export.elements.movie.votes";
	private static final String EXPORT_ELEMENT_MOVIE_OUTLINE = "movie.export.elements.movie.outline";
	private static final String EXPORT_ELEMENT_MOVIE_PLOT = "movie.export.elements.movie.plot";
	private static final String EXPORT_ELEMENT_MOVIE_TAGLINE = "movie.export.elements.movie.tagline";
	private static final String EXPORT_ELEMENT_MOVIE_RUNTIME = "movie.export.elements.movie.runtime";
	private static final String EXPORT_ELEMENT_MOVIE_THUMB = "movie.export.elements.movie.thumb";
	private static final String EXPORT_ELEMENT_MOVIE_MPAA = "movie.export.elements.movie.mpaa";
	private static final String EXPORT_ELEMENT_MOVIE_PLAYCOUNT = "movie.export.elements.movie.playcount";
	private static final String EXPORT_ELEMENT_MOVIE_WATCHED = "movie.export.elements.movie.watched";
	private static final String EXPORT_ELEMENT_MOVIE_ID = "movie.export.elements.movie.id";
	private static final String EXPORT_ELEMENT_MOVIE_TRAILER = "movie.export.elements.movie.trailer";
	private static final String EXPORT_ELEMENT_MOVIE_GENRE = "movie.export.elements.movie.genre";
	private static final String EXPORT_ELEMENT_MOVIE_CREDITS = "movie.export.elements.movie.credits";
	private static final String EXPORT_ELEMENT_MOVIE_DIRECTOR = "movie.export.elements.movie.director";
	private static final String EXPORT_ELEMENT_MOVIE_SET = "movie.export.elements.movie.set";
	private static final String EXPORT_ELEMENT_MOVIE_ACTOR = "movie.export.elements.movie.actor";
	private static final String EXPORT_ELEMENT_MOVIE_ACTOR_NAME = "movie.export.elements.movie.actor.name";
	private static final String EXPORT_ELEMENT_MOVIE_ACTOR_ROLE = "movie.export.elements.movie.actor.role";
	private static final String EXPORT_ELEMENT_MOVIE_FILEINFO = "movie.export.elements.movie.fileinfo";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS = "movie.export.elements.movie.fileinfo.streamdetails";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO = "movie.export.elements.movie.fileinfo.streamdetails.video";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_CODEC = "movie.export.elements.movie.fileinfo.streamdetails.video.codec";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_ASPECT = "movie.export.elements.movie.fileinfo.streamdetails.video.aspect";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_WIDTH = "movie.export.elements.movie.fileinfo.streamdetails.video.width";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_HEIGHT = "movie.export.elements.movie.fileinfo.streamdetails.video.height";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO = "movie.export.elements.movie.fileinfo.streamdetails.audio";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO_CODEC = "movie.export.elements.movie.fileinfo.streamdetails.audio.codec";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO_LANGUAGE = "movie.export.elements.movie.fileinfo.streamdetails.audio.language";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO_CHANNELS = "movie.export.elements.movie.fileinfo.streamdetails.audio.channels";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_SUBTITLE = "movie.export.elements.movie.fileinfo.streamdetails.subtitle";
	private static final String EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_SUBTITLE_LANGUAGE = "movie.export.elements.movie.fileinfo.streamdetails.subtitle.language";
	private static final String NFO_ELEMENT_MOVIE = "movie.nfo.elements.movie";
	private static final String NFO_ELEMENT_MOVIE_TITLE = "movie.nfo.elements.movie.title";
	private static final String NFO_ELEMENT_MOVIE_ORIGINALTITLE = "movie.nfo.elements.movie.originalTitle";
	private static final String NFO_ELEMENT_MOVIE_SORTTITLE = "movie.nfo.elements.movie.sortTitle";
	private static final String NFO_ELEMENT_MOVIE_RATING = "movie.nfo.elements.movie.rating";
	private static final String NFO_ELEMENT_MOVIE_YEAR = "movie.nfo.elements.movie.year";
	private static final String NFO_ELEMENT_MOVIE_TOP250 = "movie.nfo.elements.movie.top250";
	private static final String NFO_ELEMENT_MOVIE_VOTES = "movie.nfo.elements.movie.votes";
	private static final String NFO_ELEMENT_MOVIE_OUTLINE = "movie.nfo.elements.movie.outline";
	private static final String NFO_ELEMENT_MOVIE_PLOT = "movie.nfo.elements.movie.plot";
	private static final String NFO_ELEMENT_MOVIE_TAGLINE = "movie.nfo.elements.movie.tagline";
	private static final String NFO_ELEMENT_MOVIE_RUNTIME = "movie.nfo.elements.movie.runtime";
	private static final String NFO_ELEMENT_MOVIE_THUMB = "movie.nfo.elements.movie.thumb";
	private static final String NFO_ELEMENT_MOVIE_MPAA = "movie.nfo.elements.movie.mpaa";
	private static final String NFO_ELEMENT_MOVIE_PLAYCOUNT = "movie.nfo.elements.movie.playcount";
	private static final String NFO_ELEMENT_MOVIE_WATCHED = "movie.nfo.elements.movie.watched";
	private static final String NFO_ELEMENT_MOVIE_ID = "movie.nfo.elements.movie.id";
	private static final String NFO_ELEMENT_MOVIE_TRAILER = "movie.nfo.elements.movie.trailer";
	private static final String NFO_ELEMENT_MOVIE_GENRE = "movie.nfo.elements.movie.genre";
	private static final String NFO_ELEMENT_MOVIE_CREDITS = "movie.nfo.elements.movie.credits";
	private static final String NFO_ELEMENT_MOVIE_DIRECTOR = "movie.nfo.elements.movie.director";
	private static final String NFO_ELEMENT_MOVIE_SET = "movie.nfo.elements.movie.set";
	private static final String NFO_ELEMENT_MOVIE_ACTOR = "movie.nfo.elements.movie.actor";
	private static final String NFO_ELEMENT_MOVIE_ACTOR_NAME = "movie.nfo.elements.movie.actor.name";
	private static final String NFO_ELEMENT_MOVIE_ACTOR_ROLE = "movie.nfo.elements.movie.actor.role";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO = "movie.nfo.elements.movie.fileinfo";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS = "movie.nfo.elements.movie.fileinfo.streamdetails";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO = "movie.nfo.elements.movie.fileinfo.streamdetails.video";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_CODEC = "movie.nfo.elements.movie.fileinfo.streamdetails.video.codec";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_ASPECT = "movie.nfo.elements.movie.fileinfo.streamdetails.video.aspect";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_WIDTH = "movie.nfo.elements.movie.fileinfo.streamdetails.video.width";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_HEIGHT = "movie.nfo.elements.movie.fileinfo.streamdetails.video.height";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO = "movie.nfo.elements.movie.fileinfo.streamdetails.audio";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CODEC = "movie.nfo.elements.movie.fileinfo.streamdetails.audio.codec";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_LANGUAGE = "movie.nfo.elements.movie.fileinfo.streamdetails.audio.language";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CHANNELS = "movie.nfo.elements.movie.fileinfo.streamdetails.audio.channels";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE = "movie.nfo.elements.movie.fileinfo.streamdetails.subtitle";
	private static final String NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE_LANGUAGE = "movie.nfo.elements.movie.fileinfo.streamdetails.subtitle.language";
	private static final String LIBRARY_PATH_KEY = "movie.import.libraryPath";
	private static final String NAME_REGEX_KEY = "movie.import.regexName";
	private static final String YEAR_REGEX_KEY = "movie.import.regexYear";
	private static final String MATCH_NAME_ON_PARENT_FOLDER_KEY = "movie.import.matchNameOnParentFolder";
	private static final String MATCH_YEAR_ON_PARENT_FOLDER_KEY = "movie.import.matchYearOnParentFolder";
	private static final String MATCH_NAME_ON_NFO = "movie.import.matchNameOnNfo";
	private static final String PARENT_FOLDER_NAME_MUST_MATCH_MOVIE = "movie.import.parentFolderNameMustMatchMovie";
	private static final String MOVIE_EXTENSIONS_KEY = "movie.import.movieExtensions";
	private static final String IGNORE_STRINGS_KEY = "movie.import.ignoreStrings";
	private static final String USE_POSTERS_KEY = "movie.import.usePosters";
	private static final String USE_FANART_KEY = "movie.import.useFanart";
	private static final String USE_EXTRA_THUMBS_KEY = "movie.import.useExtraThumbs";
	private static final String POSTER_NAME_KEY = "movie.import.posterName";
	private static final String FANART_NAME_KEY = "movie.import.fanartName";
	private static final String EXTRA_THUMBS_FOLDER_NAME_KEY = "movie.import.extraThumbsFolderName";
	private static final String EXTRA_THUMBS_PATTERN_KEY = "movie.import.extraThumbsPattern";
	private static final String EXTRA_THUMBS_FORMAT_KEY = "movie.import.extraThumbsFormat";
	private static final String TMBD_API_KEY = "movie.scrape.tmdb.apiKey";

	public static MovieSettings load() {
		final File propertiesFile = GlobalSettingsFactory.getPropertiesFile();

		// Read properties
		final Properties properties = PropertiesUtils.readPropertiesFile(propertiesFile);

		// Parse the properties
		return parse(properties);
	}

	/**
	 * Serializes a movie settings instance into a properties file instance
	 * @param settings the settings to serialize
	 * @return a properties file instance
	 */
	public static Properties serialize(MovieSettings settings) {
		if(settings == null) {
			throw new IllegalArgumentException("The settings parameter cannot be null");
		}

		final Properties properties = new Properties();
		properties.setProperty(LIBRARY_PATH_KEY, settings.getLibraryPath());
		properties.setProperty(NAME_REGEX_KEY, settings.getNameRegex().pattern());
		properties.setProperty(YEAR_REGEX_KEY, settings.getYearRegex().pattern());
		properties.setProperty(MATCH_NAME_ON_PARENT_FOLDER_KEY, PropertiesUtils.serializeBoolean(settings.matchNameOnParentFolder()));
		properties.setProperty(MATCH_YEAR_ON_PARENT_FOLDER_KEY, PropertiesUtils.serializeBoolean(settings.matchYearOnParentFolder()));
		properties.setProperty(MATCH_NAME_ON_NFO, PropertiesUtils.serializeBoolean(settings.matchNameOnNfo()));
		properties.setProperty(PARENT_FOLDER_NAME_MUST_MATCH_MOVIE, PropertiesUtils.serializeBoolean(settings.parentFolderNameMustMatchMovie()));
		properties.setProperty(MOVIE_EXTENSIONS_KEY, PropertiesUtils.serializeStringArray(settings.getMovieExtensions()));
		properties.setProperty(IGNORE_STRINGS_KEY, PropertiesUtils.serializeStringArray(settings.getIgnoreStrings()));
		properties.setProperty(USE_POSTERS_KEY, PropertiesUtils.serializeBoolean(settings.usePosters()));
		properties.setProperty(USE_FANART_KEY, PropertiesUtils.serializeBoolean(settings.useFanart()));
		properties.setProperty(USE_EXTRA_THUMBS_KEY, PropertiesUtils.serializeBoolean(settings.useExtraThumbs()));
		properties.setProperty(POSTER_NAME_KEY, settings.getPosterName());
		properties.setProperty(FANART_NAME_KEY, settings.getFanartName());
		properties.setProperty(EXTRA_THUMBS_FOLDER_NAME_KEY, settings.getExtraThumbsFolderName());
		properties.setProperty(EXTRA_THUMBS_PATTERN_KEY, settings.getExtraThumbsPattern() == null ? null : settings.getExtraThumbsPattern().pattern());
		properties.setProperty(EXTRA_THUMBS_FORMAT_KEY, settings.getExtraThumbsFormat());
		properties.setProperty(EXPORT_PRETTY_FORMAT, PropertiesUtils.serializeBoolean(settings.getPrettyFormatNfo()));
		properties.setProperty(EXPORT_ADD_EMPTY_NODES, PropertiesUtils.serializeBoolean(settings.getAddEmptyNfoNodes()));
		properties.setProperty(TMBD_API_KEY, settings.getTmdbApiKey());

		properties.setProperty(NFO_ELEMENT_MOVIE, settings.getNfoConstants().MOVIE);
		properties.setProperty(NFO_ELEMENT_MOVIE_ACTOR, settings.getNfoConstants().ACTOR);
		properties.setProperty(NFO_ELEMENT_MOVIE_ACTOR_NAME, settings.getNfoConstants().ACTOR_NAME);
		properties.setProperty(NFO_ELEMENT_MOVIE_ACTOR_ROLE, settings.getNfoConstants().ACTOR_ROLE);
		properties.setProperty(NFO_ELEMENT_MOVIE_CREDITS, settings.getNfoConstants().CREDITS);
		properties.setProperty(NFO_ELEMENT_MOVIE_DIRECTOR, settings.getNfoConstants().DIRECTOR);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO, settings.getNfoConstants().FILE_INFO);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS, settings.getNfoConstants().STREAM_DETAILS);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO, settings.getNfoConstants().STREAM_DETAILS_AUDIO);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CHANNELS, settings.getNfoConstants().STREAM_DETAILS_AUDIO_CHANNELS);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CODEC, settings.getNfoConstants().STREAM_DETAILS_AUDIO_CODEC);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_LANGUAGE, settings.getNfoConstants().STREAM_DETAILS_AUDIO_LANGUAGE);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE, settings.getNfoConstants().STREAM_DETAILS_SUBTITLE);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE_LANGUAGE, settings.getNfoConstants().STREAM_DETAILS_SUBTITLE_LANGUAGE);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO, settings.getNfoConstants().STREAM_DETAILS_VIDEO);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_ASPECT, settings.getNfoConstants().STREAM_DETAILS_VIDEO_ASPECT);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_CODEC, settings.getNfoConstants().STREAM_DETAILS_VIDEO_CODEC);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_HEIGHT, settings.getNfoConstants().STREAM_DETAILS_VIDEO_HEIGHT);
		properties.setProperty(NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_WIDTH, settings.getNfoConstants().STREAM_DETAILS_VIDEO_WIDTH);
		properties.setProperty(NFO_ELEMENT_MOVIE_GENRE, settings.getNfoConstants().GENRE);
		properties.setProperty(NFO_ELEMENT_MOVIE_ID, settings.getNfoConstants().ID);
		properties.setProperty(NFO_ELEMENT_MOVIE_MPAA, settings.getNfoConstants().MPAA);
		properties.setProperty(NFO_ELEMENT_MOVIE_ORIGINALTITLE, settings.getNfoConstants().ORIGINAL_TITLE);
		properties.setProperty(NFO_ELEMENT_MOVIE_OUTLINE, settings.getNfoConstants().OUTLINE);
		properties.setProperty(NFO_ELEMENT_MOVIE_PLAYCOUNT, settings.getNfoConstants().PLAY_COUNT);
		properties.setProperty(NFO_ELEMENT_MOVIE_PLOT, settings.getNfoConstants().PLOT);
		properties.setProperty(NFO_ELEMENT_MOVIE_RATING, settings.getNfoConstants().RATING);
		properties.setProperty(NFO_ELEMENT_MOVIE_RUNTIME, settings.getNfoConstants().RUNTIME);
		properties.setProperty(NFO_ELEMENT_MOVIE_SET, settings.getNfoConstants().SET);
		properties.setProperty(NFO_ELEMENT_MOVIE_SORTTITLE, settings.getNfoConstants().SORT_TITLE);
		properties.setProperty(NFO_ELEMENT_MOVIE_TAGLINE, settings.getNfoConstants().TAGLINE);
		properties.setProperty(NFO_ELEMENT_MOVIE_THUMB, settings.getNfoConstants().THUMB);
		properties.setProperty(NFO_ELEMENT_MOVIE_TITLE, settings.getNfoConstants().TITLE);
		properties.setProperty(NFO_ELEMENT_MOVIE_TOP250, settings.getNfoConstants().TOP250);
		properties.setProperty(NFO_ELEMENT_MOVIE_TRAILER, settings.getNfoConstants().TRAILER);
		properties.setProperty(NFO_ELEMENT_MOVIE_VOTES, settings.getNfoConstants().VOTES);
		properties.setProperty(NFO_ELEMENT_MOVIE_WATCHED, settings.getNfoConstants().WATCHED);
		properties.setProperty(NFO_ELEMENT_MOVIE_YEAR, settings.getNfoConstants().YEAR);

		properties.setProperty(EXPORT_ELEMENT_MOVIE, PropertiesUtils.serializeBoolean(settings.getExportNodes().MOVIE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_ACTOR, PropertiesUtils.serializeBoolean(settings.getExportNodes().ACTOR));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_ACTOR_NAME, PropertiesUtils.serializeBoolean(settings.getExportNodes().ACTOR_NAME));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_ACTOR_ROLE, PropertiesUtils.serializeBoolean(settings.getExportNodes().ACTOR_ROLE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_CREDITS, PropertiesUtils.serializeBoolean(settings.getExportNodes().CREDITS));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_DIRECTOR, PropertiesUtils.serializeBoolean(settings.getExportNodes().DIRECTOR));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEINFO, PropertiesUtils.serializeBoolean(settings.getExportNodes().FILE_INFO));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_AUDIO));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO_CHANNELS, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_AUDIO_CHANNELS));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO_CODEC, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_AUDIO_CODEC));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_AUDIO_LANGUAGE, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_AUDIO_LANGUAGE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_SUBTITLE, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_SUBTITLE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_SUBTITLE_LANGUAGE, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_SUBTITLE_LANGUAGE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_VIDEO));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_ASPECT, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_VIDEO_ASPECT));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_CODEC, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_VIDEO_CODEC));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_HEIGHT, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_VIDEO_HEIGHT));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_FILEIEXPORT_STREAMDETAILS_VIDEO_WIDTH, PropertiesUtils.serializeBoolean(settings.getExportNodes().STREAM_DETAILS_VIDEO_WIDTH));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_GENRE, PropertiesUtils.serializeBoolean(settings.getExportNodes().GENRE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_ID, PropertiesUtils.serializeBoolean(settings.getExportNodes().ID));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_MPAA, PropertiesUtils.serializeBoolean(settings.getExportNodes().MPAA));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_ORIGINALTITLE, PropertiesUtils.serializeBoolean(settings.getExportNodes().ORIGINAL_TITLE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_OUTLINE, PropertiesUtils.serializeBoolean(settings.getExportNodes().OUTLINE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_PLAYCOUNT, PropertiesUtils.serializeBoolean(settings.getExportNodes().PLAY_COUNT));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_PLOT, PropertiesUtils.serializeBoolean(settings.getExportNodes().PLOT));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_RATING, PropertiesUtils.serializeBoolean(settings.getExportNodes().RATING));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_RUNTIME, PropertiesUtils.serializeBoolean(settings.getExportNodes().RUNTIME));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_SET, PropertiesUtils.serializeBoolean(settings.getExportNodes().SET));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_SORTTITLE, PropertiesUtils.serializeBoolean(settings.getExportNodes().SORT_TITLE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_TAGLINE, PropertiesUtils.serializeBoolean(settings.getExportNodes().TAGLINE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_THUMB, PropertiesUtils.serializeBoolean(settings.getExportNodes().THUMB));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_TITLE, PropertiesUtils.serializeBoolean(settings.getExportNodes().TITLE));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_TOP250, PropertiesUtils.serializeBoolean(settings.getExportNodes().TOP250));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_TRAILER, PropertiesUtils.serializeBoolean(settings.getExportNodes().TRAILER));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_VOTES, PropertiesUtils.serializeBoolean(settings.getExportNodes().VOTES));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_WATCHED, PropertiesUtils.serializeBoolean(settings.getExportNodes().WATCHED));
		properties.setProperty(EXPORT_ELEMENT_MOVIE_YEAR, PropertiesUtils.serializeBoolean(settings.getExportNodes().YEAR));

		return properties;
	}

	private static MovieSettings parse(Properties properties) {
		if(properties == null) {
			throw new IllegalArgumentException("The properties parameter cannot be null");
		}

		final String libraryPath = PropertiesUtils.parseString(properties, LIBRARY_PATH_KEY, null, false);
		final Pattern nameRegex = Pattern.compile(PropertiesUtils.parseString(properties, NAME_REGEX_KEY, "", false));
		final Pattern yearRegex = Pattern.compile(PropertiesUtils.parseString(properties, YEAR_REGEX_KEY, "", false));
		final boolean matchNameOnParentFolder = PropertiesUtils.parseBoolean(properties, MATCH_NAME_ON_PARENT_FOLDER_KEY, false, false);
		final boolean matchYearOnParentFolder = PropertiesUtils.parseBoolean(properties, MATCH_YEAR_ON_PARENT_FOLDER_KEY, false, false);
		final boolean parentFolderNameMustMatchMovie = PropertiesUtils.parseBoolean(properties, PARENT_FOLDER_NAME_MUST_MATCH_MOVIE, false, false);
		final boolean matchNameOnNfo = PropertiesUtils.parseBoolean(properties, MATCH_NAME_ON_NFO, false, false);
		final String tmdbApiKey = PropertiesUtils.parseString(properties, TMBD_API_KEY, null, true);
		final String[] movieExtensions = PropertiesUtils.parseStringArray(properties, MOVIE_EXTENSIONS_KEY, new String[] {}, false);
		final String[] ignoreStrings = PropertiesUtils.parseStringArray(properties, IGNORE_STRINGS_KEY, new String[] {}, false);
		final boolean usePosters = PropertiesUtils.parseBoolean(properties, USE_POSTERS_KEY, false, false);
		final boolean useFanart = PropertiesUtils.parseBoolean(properties, USE_FANART_KEY, false, false);
		final boolean useExtraThumbs = PropertiesUtils.parseBoolean(properties, USE_EXTRA_THUMBS_KEY, false, false);
		final String posterName = PropertiesUtils.parseString(properties, POSTER_NAME_KEY, null, true);
		final String fanartName = PropertiesUtils.parseString(properties, FANART_NAME_KEY, null, true);
		final String extraThumbsFolderName = PropertiesUtils.parseString(properties, EXTRA_THUMBS_FOLDER_NAME_KEY, null,true);
		final Pattern extraThumbsPattern = Pattern.compile(PropertiesUtils.parseString(properties, EXTRA_THUMBS_PATTERN_KEY, "", true));
		final String extraThumbsFormat = PropertiesUtils.parseString(properties, EXTRA_THUMBS_FORMAT_KEY, null, true);
		final boolean prettyFormatNfos = PropertiesUtils.parseBoolean(properties, EXPORT_PRETTY_FORMAT, true, true);
		final boolean addEmptyNfoNodes = PropertiesUtils.parseBoolean(properties, EXPORT_ADD_EMPTY_NODES, false, true);

		final MovieNfoConstants nfoConstants = new MovieNfoConstants();
		nfoConstants.MOVIE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE, null, false);
		nfoConstants.ACTOR = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_ACTOR, null, false);
		nfoConstants.ACTOR_NAME = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_ACTOR_NAME, null, false);
		nfoConstants.ACTOR_ROLE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_ACTOR_ROLE, null, false);
		nfoConstants.CREDITS = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_CREDITS, null, false);
		nfoConstants.DIRECTOR = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_DIRECTOR, null, false);
		nfoConstants.FILE_INFO = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO, null, false);
		nfoConstants.GENRE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_GENRE, null, false);
		nfoConstants.ID = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_ID, null, false);
		nfoConstants.MPAA = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_MPAA, null, false);
		nfoConstants.ORIGINAL_TITLE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_ORIGINALTITLE, null, false);
		nfoConstants.OUTLINE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_OUTLINE, null, false);
		nfoConstants.PLAY_COUNT = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_PLAYCOUNT, null, false);
		nfoConstants.PLOT = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_PLOT, null, false);
		nfoConstants.RATING = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_RATING, null, false);
		nfoConstants.RUNTIME = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_RUNTIME, null, false);
		nfoConstants.SET = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_SET, null, false);
		nfoConstants.SORT_TITLE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_SORTTITLE, null, false);
		nfoConstants.STREAM_DETAILS = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS, null, false);
		nfoConstants.STREAM_DETAILS_AUDIO = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO, null, false);
		nfoConstants.STREAM_DETAILS_AUDIO_CHANNELS = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CHANNELS, null, false);
		nfoConstants.STREAM_DETAILS_AUDIO_CODEC = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CODEC, null, false);
		nfoConstants.STREAM_DETAILS_AUDIO_LANGUAGE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_LANGUAGE, null, false);
		nfoConstants.STREAM_DETAILS_SUBTITLE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE, null, false);
		nfoConstants.STREAM_DETAILS_SUBTITLE_LANGUAGE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE_LANGUAGE, null, false);
		nfoConstants.STREAM_DETAILS_VIDEO = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO, null, false);
		nfoConstants.STREAM_DETAILS_VIDEO_ASPECT = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_ASPECT, null, false);
		nfoConstants.STREAM_DETAILS_VIDEO_CODEC = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_CODEC, null, false);
		nfoConstants.STREAM_DETAILS_VIDEO_HEIGHT = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_HEIGHT, null, false);
		nfoConstants.STREAM_DETAILS_VIDEO_WIDTH = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_WIDTH, null, false);
		nfoConstants.TAGLINE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_TAGLINE, null, false);
		nfoConstants.THUMB = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_THUMB, null, false);
		nfoConstants.TITLE = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_TITLE, null, false);
		nfoConstants.TOP250 = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_TOP250, null, false);
		nfoConstants.TRAILER = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_TRAILER, null, false);
		nfoConstants.VOTES = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_VOTES, null, false);
		nfoConstants.WATCHED = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_WATCHED, null, false);
		nfoConstants.YEAR = PropertiesUtils.parseString(properties, NFO_ELEMENT_MOVIE_YEAR, null, false);

		final MovieExportNodes exportNodes = new MovieExportNodes();
		exportNodes.MOVIE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE, true, false);
		exportNodes.ACTOR = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_ACTOR, true, false);
		exportNodes.ACTOR_NAME = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_ACTOR_NAME, true, false);
		exportNodes.ACTOR_ROLE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_ACTOR_ROLE, true, false);
		exportNodes.CREDITS = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_CREDITS, true, false);
		exportNodes.DIRECTOR = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_DIRECTOR, true, false);
		exportNodes.FILE_INFO = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO, true, false);
		exportNodes.GENRE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_GENRE, true, false);
		exportNodes.ID = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_ID, true, false);
		exportNodes.MPAA = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_MPAA, true, false);
		exportNodes.ORIGINAL_TITLE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_ORIGINALTITLE, true, false);
		exportNodes.OUTLINE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_OUTLINE, true, false);
		exportNodes.PLAY_COUNT = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_PLAYCOUNT, true, false);
		exportNodes.PLOT = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_PLOT, true, false);
		exportNodes.RATING = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_RATING, true, false);
		exportNodes.RUNTIME = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_RUNTIME, true, false);
		exportNodes.SET = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_SET, true, false);
		exportNodes.SORT_TITLE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_SORTTITLE, true, false);
		exportNodes.STREAM_DETAILS = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS, true, false);
		exportNodes.STREAM_DETAILS_AUDIO = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO, true, false);
		exportNodes.STREAM_DETAILS_AUDIO_CHANNELS = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CHANNELS, true, false);
		exportNodes.STREAM_DETAILS_AUDIO_CODEC = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_CODEC, true, false);
		exportNodes.STREAM_DETAILS_AUDIO_LANGUAGE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_AUDIO_LANGUAGE, true, false);
		exportNodes.STREAM_DETAILS_SUBTITLE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE, true, false);
		exportNodes.STREAM_DETAILS_SUBTITLE_LANGUAGE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_SUBTITLE_LANGUAGE, true, false);
		exportNodes.STREAM_DETAILS_VIDEO = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO, true, false);
		exportNodes.STREAM_DETAILS_VIDEO_ASPECT = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_ASPECT, true, false);
		exportNodes.STREAM_DETAILS_VIDEO_CODEC = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_CODEC, true, false);
		exportNodes.STREAM_DETAILS_VIDEO_HEIGHT = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_HEIGHT, true, false);
		exportNodes.STREAM_DETAILS_VIDEO_WIDTH = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_FILEINFO_STREAMDETAILS_VIDEO_WIDTH, true, false);
		exportNodes.TAGLINE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_TAGLINE, true, false);
		exportNodes.THUMB = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_THUMB, true, false);
		exportNodes.TITLE = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_TITLE, true, false);
		exportNodes.TOP250 = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_TOP250, true, false);
		exportNodes.TRAILER = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_TRAILER, true, false);
		exportNodes.VOTES = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_VOTES, true, false);
		exportNodes.WATCHED = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_WATCHED, true, false);
		exportNodes.YEAR = PropertiesUtils.parseBoolean(properties, NFO_ELEMENT_MOVIE_YEAR, true, false);

		return new MovieSettingsImpl(libraryPath, nameRegex, yearRegex, matchNameOnParentFolder,
				matchYearOnParentFolder, parentFolderNameMustMatchMovie, matchNameOnNfo,
				tmdbApiKey, movieExtensions, ignoreStrings, usePosters, useFanart, useExtraThumbs,
				posterName, fanartName, extraThumbsFolderName, extraThumbsPattern, extraThumbsFormat,
				nfoConstants, prettyFormatNfos, addEmptyNfoNodes, exportNodes);
	}

}
